import {GetQtController} from "../QtUtils";

export default
class HCWebRTCPlayer{
    constructor()
    {
        /*信令服务器相关参数初始化*/
        this.SignalServerIP = "127.0.0.1";
        this.SignalServerPort = "3333";
        this.streamServerID=-1;
        this.streamServerPort = 8090;
        this.streamServerHost = "";
        this.SignalWebSocketID = null;
        this.LoacalAdress = null;
        this.SignalWebSocketType = "RenderClient";     //RenderClient | RenderServer;
        this.SignalWebSocketConnection = null;


        /*webRTC视频窗口相关参数初始化*/
        this.RenderWndwidth = 1920;
        this.RenderWndHeight = 1080;
        this.RenderWnd = null;
        this.RenderWnd_ZIndex = 1;

        /*webRTC连接相关参数初始化*/
        this.WebRTCPeerConnection = null;
        this.WebRTCPeerConfig = null;
        this.WebRTCDataChannel = null;
        this.isNeedAudioStream = 0;                    //1: 获取   -    0:不获取
        this.isNeedVideoStream = 1;
        this.WebRTCDataChannelOptions = {ordered: true};
        this.outsideConnectOption = null;    //外部连接参数
    }

    _initParam(params)
    {
        this.SignalServerIP = params.ip;
        this.SignalServerPort = params.port;

        if(params.videoWnd)
        {
            this.RenderWnd = params.videoWnd;
        }
        this.RenderWndWidget = params.width;
        this.RenderWndHeight = params.height;
        
        this.streamServerID  = params.streamServerID;
        //赋值需要请求渲染流的IP和端口
        this.streamServerPort=params.streamServerPort;
        this.streamServerHost=params.streamServerHost;

        this.outsideConnectOption = params.outsideConnectOption;

        this._ConnectSignalServer();
        this._initMediaWnd();
    }

    _ConnectSignalServer()
    {
        let preHost = 'ws://';
        if(GetQtController().inParam.dataUrl.indexOf('https') != -1) {
          preHost = 'wss://';
        }
        let SignalServerURL = preHost + this.SignalServerIP + ":" + this.SignalServerPort;
        console.log('webrtc_websocket',SignalServerURL);
        this.SignalWebSocketConnection = new WebSocket(SignalServerURL, "json");

        this.SignalWebSocketConnection.onopen = this.CB_HandleWebSocketOpen.bind(this);
        this.SignalWebSocketConnection.onerror = this.CB_HandleWebSocketError.bind(this);
        this.SignalWebSocketConnection.onmessage = this.CB_HandleWebSocketMsg.bind(this);
        this.SignalWebSocketConnection.onclose = this.CB_HandleWebSocketClose.bind(this);
    }

    _OpenWebRtcPlayer()
    {
        this._createPeerConnection();
    }

    _initMediaWnd()
    {
        if(this.RenderWnd == null)
        {
            this.RenderWnd = document.createElement('video');
            this.RenderWnd.id = 'webRTC_video';
            this.RenderWnd.width = this.RenderWndwidth;
            this.RenderWnd.height = this.RenderWndHeight;
            this.RenderWnd.autoplay = true;
            this.RenderWnd.style.cssText = `position: absolute;width: 100%;height: 100%;left:0px;top:0px;z-index:"${this.RenderWnd_ZIndex}";`;
            document.body.append(this.RenderWnd);
        }
        else
        {
            this.RenderWnd.width = this.RenderWndwidth;
            this.RenderWnd.height = this.RenderWndHeight;
            this.RenderWnd.autoplay = true;
            this.RenderWnd.style.cssText = `position: absolute;width: 100%;height: 100%;left:0px;top:0px;z-index:-999;`;
        }
		
        // this.RenderWnd.addEventListener('canplaythrough', function(e)
		// {
        //       console.log('提示视频能够不停顿地一直播放')
        //       console.log(e)
        // })
		
    }

    _getMediaElement()
    {
        return this.RenderWnd;
    }

    CB_HandleWebSocketOpen(evt)
    {
        let _ServerListAddr = document.location.host;
        console.log("[webRTC-serverlistAddress]:" ,_ServerListAddr);
        let funParams = {
            type: "client_type",
            value: this.SignalWebSocketType,
            id:    this.streamServerID,
            host:  this.streamServerHost,
            port: this.streamServerPort,
            serverAddr: _ServerListAddr,
            outsideConnectOption:this.outsideConnectOption,         //外部连接参数
        };
        this._sendMSGtoSignalServer(funParams);
    }

    CB_HandleWebSocketError(evt)
    {
        console.dir("[webRTC-websocketError]:" ,evt);
    }

    CB_HandleWebSocketClose(evt)
    {

    }

    CB_HandleWebSocketMsg(evt)
    {
        let SignalMSG = JSON.parse(evt.data);
        switch(SignalMSG.type)
        {
            case "id":
                this.SignalWebSocketID = SignalMSG.id;
                this.WebRTCPeerConfig = SignalMSG.config;
                this.LoacalAdress = SignalMSG.ip;
                console.log("[webRTC-localconnectionID]:" ,this.SignalWebSocketID);
                console.log("[webRTC-localconnectionIP]:" ,this.LoacalAdress);
                console.log("[webRTC-peerconnectionConfig]:",this.WebRTCPeerConfig);
                break;
            case "video-answer":
                this.webSocket_handleVideoAnswerMsg(SignalMSG);
                break;
            case "ice-candidate":
                this.webSocket_handleNewICECandidateMsg(SignalMSG);
                break;
            case "quit":
                if(SignalMSG.ip == this.streamServerHost)
                {
                    this.SignalWebSocketConnection.close();
                    alert("渲染端<" + SignalMSG.ip + ">已退出!!!");
                    // console.log("[webRTC-peerconnection]:" + "渲染端<" + SignalMSG.ip + ">已退出!!!");

                }
                break;
            case "no-render":
                this.SignalWebSocketConnection.close();
                alert(SignalMSG.value);
                // console.log("[webRTC-peerconnection]:" + SignalMSG.value);

        }
    }

    _createPeerConnection()
    {
        this._closePeerConnection();
        this.WebRTCPeerConnection = new RTCPeerConnection(this.WebRTCPeerConfig);

        this.WebRTCPeerConnection.onnegotiationneeded = this.webRTC_CB_handleNegotiationNeededEvent.bind(this);
        this.WebRTCPeerConnection.onicecandidate = this.webRTC_CB_handleICECandidateEvent.bind(this);
        // this.WebRTCPeerConnection.oniceconnectionstatechange = this.webRTC_CB_handleICEConnectionStateChangeEvent.bind(this);
        // this.WebRTCPeerConnection.onicegatheringstatechange = this.webRTC_CB_handleICEGatheringStateChangeEvent.bind(this);
        // this.WebRTCPeerConnection.onsignalingstatechange = this.webRTC_CB_handleSignalingStateChangeEvent.bind(this);
        this.WebRTCPeerConnection.ontrack = this.webRTC_CB_handleTrackEvent.bind(this);

        this.WebRTCDataChannel = this.WebRTCPeerConnection.createDataChannel("HC_WebRTC_DataChannel", this.WebRTCDataChannelOptions);
        this.WebRTCDataChannel.onopen = this.webRTC_CB_DataChannelOnOpen.bind(this);
        this.WebRTCDataChannel.onclose = this.webRTC_CB_DataChannelOnClose.bind(this);
        this.WebRTCDataChannel.onmessage = this.webRTC_CB_DataChannelOnMessage.bind(this);
    }

    _closePeerConnection()
    {
        if(this.WebRTCPeerConnection)
        {
            this.WebRTCPeerConnection.close();
            this.WebRTCPeerConnection = null;
        }
    }

    async webSocket_handleVideoAnswerMsg(msg)
    {
        console.log("[webRTC-peerconnection]:" + "收到answer=>" , msg);
        let loacldesc = new RTCSessionDescription(msg.sdp);
        await this.WebRTCPeerConnection.setRemoteDescription(loacldesc);
    }

    async webSocket_handleNewICECandidateMsg(msg)
    {
        console.log("[webRTC-peerconnection]:" + "收到IceCandidate=>" , msg);
        if(msg.candidate)
        {
            let candidate = new RTCIceCandidate(msg.candidate);
            await this.WebRTCPeerConnection.addIceCandidate(candidate);
        }
    }

    webRTC_CB_DataChannelOnOpen(event) {
      if (this.SignalWebSocketConnection && this.SignalWebSocketConnection.readyState === 1) {
        console.log("[webRTC-datachannel]:" + "WebRTC datachannel connected, waiting for video!");
      }
    }


    webRTC_CB_DataChannelOnClose(event)
    {
      console.log("[webRTC-datachannel]:" + "webRTC_CB_DataChannelOnClose");
    }

    webRTC_CB_DataChannelOnMessage(event)
    {
        //后期可以融合走 H265流及鼠标命令消息
        console.log("[webRTC-datachannel]:" + e.data);
    }

    async webRTC_CB_handleNegotiationNeededEvent()
    {
        try
        {
            console.log("[webRTC-peerconnection]:" + "---Create Offer---");
            let offerSDPConstraints =
            {
                iceRestart: true,
                offerToReceiveAudio: this.isNeedAudioStream,
                offerToReceiveVideo: this.isNeedVideoStream
            };
            const webrtc_offer = await this.WebRTCPeerConnection.createOffer(offerSDPConstraints);
            if(this.WebRTCPeerConnection.signalingState != "stable")
            {
                console.log("[webRTC-peerconnection]:" + "connection isn't stable yet!");
                return;
            }

            await this.WebRTCPeerConnection.setLocalDescription(webrtc_offer);

            this._sendMSGtoSignalServer({
                send: this.LoacalAdress,
                sendtype: this.SignalWebSocketType,
                id:     this.streamServerID,
                target: this.streamServerHost,
                type: "video-offer",
                sdp: this.WebRTCPeerConnection.localDescription
            });
        }
        catch(e)
        {
            console.log("[webRTC-peerconnection]:" +"error occurred while handling the negotiationneeded event!");
        }
    }

    async webRTC_CB_handleICECandidateEvent(event)
    {
        if(event.candidate)
        {
            console.log("[webRTC-peerconnection]:" + "发送iceiceice=>" , event.candidate);
            this._sendMSGtoSignalServer({
                type: "ice-candidate",
                id:     this.streamServerID,	
                target: this.streamServerHost,
                send: this.LoacalAdress,
                sendtype: this.SignalWebSocketType,
                candidate: event.candidate
            });
        }
    }

    async webRTC_CB_handleICEConnectionStateChangeEvent(event)
    {
    }

    async webRTC_CB_handleICEGatheringStateChangeEvent(event)
    {
    }

    async webRTC_CB_handleSignalingStateChangeEvent(event)
    {
    }

    async webRTC_CB_handleTrackEvent(event)
    {
        if(this.RenderWnd)
        {
            if(this.RenderWnd.srcObject != event.streams[0])
            {
                console.log("[webRTC-peerconnection]:" + "收到流数据=>:", event);
                console.log("[webRTC-peerconnection]:" + "mediawnd=>:", this.RenderWnd);
                this.RenderWnd.srcObject = event.streams[0];
            }
        }
    }

    _sendMSGtoSignalServer(msg)
    {
        let msgJSON = JSON.stringify(msg);
        this.SignalWebSocketConnection.send(msgJSON);
    }
}
